// src/scenarios/mod.rs

//! 应用场景模块
//! 提供不同行业的语义转换场景示例

pub mod manufacturing;
pub mod robotics;
pub mod supply_chain;
pub mod traffic_engineering;
pub mod smart_campus;
pub mod energy_management;
pub mod building_automation;

pub use manufacturing::*;
pub use robotics::*;
pub use supply_chain::*;
pub use traffic_engineering::*;
pub use smart_campus::*;
pub use energy_management::*;
pub use building_automation::*;

use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// 通用场景特征
pub trait Scenario {
    /// 场景名称
    fn name(&self) -> &'static str;

    /// 场景描述
    fn description(&self) -> &'static str;

    /// 应用行业
    fn industry(&self) -> &'static str;

    /// 获取转换规则
    fn get_transformation_rules(&self) -> ScenarioTransformationRules;

    /// 获取OPC UA模型模板
    fn get_opcua_model_template(&self) -> ScenarioModelTemplate;

    /// 获取示例数据
    fn get_sample_data(&self) -> Vec<ScenarioSampleData>;

    /// 场景特定的语义映射
    fn get_semantic_mappings(&self) -> HashMap<String, String>;
}

/// 场景转换规则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScenarioTransformationRules {
    /// 规则名称
    pub rule_name: String,
    /// 数据源类型映射
    pub data_source_mappings: HashMap<String, String>,
    /// 单位转换规则
    pub unit_conversions: HashMap<String, UnitConversion>,
    /// 数据类型转换规则
    pub data_type_mappings: HashMap<String, String>,
    /// 语义标签映射
    pub semantic_mappings: HashMap<String, Vec<String>>,
    /// 约束条件
    pub constraints: Vec<ScenarioConstraint>,
}

/// 单位转换规则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UnitConversion {
    /// 源单位
    pub from_unit: String,
    /// 目标单位
    pub to_unit: String,
    /// 转换系数
    pub conversion_factor: f64,
    /// 转换公式（可选）
    pub conversion_formula: Option<String>,
}

/// 场景约束
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScenarioConstraint {
    /// 约束名称
    pub name: String,
    /// 约束类型
    pub constraint_type: String,
    /// 字段名
    pub field: String,
    /// 约束值
    pub value: serde_json::Value,
    /// 描述
    pub description: Option<String>,
}

/// 场景模型模板
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScenarioModelTemplate {
    /// 模板名称
    pub template_name: String,
    /// 命名空间
    pub namespaces: Vec<String>,
    /// 对象类型定义
    pub object_types: Vec<ObjectTypeTemplate>,
    /// 变量类型定义
    pub variable_types: Vec<VariableTypeTemplate>,
    /// 引用类型定义
    pub reference_types: Vec<ReferenceTypeTemplate>,
}

/// 对象类型模板
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ObjectTypeTemplate {
    /// 类型名称
    pub type_name: String,
    /// 描述
    pub description: Option<String>,
    /// 父类型
    pub parent_type: Option<String>,
    /// 属性
    pub properties: Vec<PropertyTemplate>,
    /// 方法
    pub methods: Vec<MethodTemplate>,
}

/// 变量类型模板
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VariableTypeTemplate {
    /// 类型名称
    pub type_name: String,
    /// 数据类型
    pub data_type: String,
    /// 描述
    pub description: Option<String>,
    /// 单位
    pub unit: Option<String>,
    /// 最小值
    pub min_value: Option<f64>,
    /// 最大值
    pub max_value: Option<f64>,
}

/// 引用类型模板
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReferenceTypeTemplate {
    /// 类型名称
    pub type_name: String,
    /// 描述
    pub description: Option<String>,
    /// 父类型
    pub parent_type: Option<String>,
    /// 对称性
    pub symmetric: bool,
}

/// 属性模板
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PropertyTemplate {
    /// 属性名称
    pub name: String,
    /// 数据类型
    pub data_type: String,
    /// 描述
    pub description: Option<String>,
    /// 单位
    pub unit: Option<String>,
    /// 是否必选
    pub required: bool,
    /// 默认值
    pub default_value: Option<serde_json::Value>,
}

/// 方法模板
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MethodTemplate {
    /// 方法名称
    pub name: String,
    /// 描述
    pub description: Option<String>,
    /// 输入参数
    pub input_arguments: Vec<ArgumentTemplate>,
    /// 输出参数
    pub output_arguments: Vec<ArgumentTemplate>,
}

/// 参数模板
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ArgumentTemplate {
    /// 参数名称
    pub name: String,
    /// 数据类型
    pub data_type: String,
    /// 描述
    pub description: Option<String>,
    /// 单位
    pub unit: Option<String>,
}

/// 场景示例数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScenarioSampleData {
    /// 数据ID
    pub data_id: String,
    /// 数据源类型
    pub data_source_type: String,
    /// 原始数据
    pub raw_data: serde_json::Value,
    /// 预期的OPC UA表示
    pub expected_opcua: serde_json::Value,
    /// 数据描述
    pub description: Option<String>,
    /// 数据分类
    pub category: Option<String>,
}

/// 场景管理器
pub struct SceneManager {
    /// 注册的场景
    scenarios: HashMap<String, Box<dyn Scenario + Send + Sync>>,
}

impl SceneManager {
    /// 创建新的场景管理器
    pub fn new() -> Self {
        let mut manager = Self {
            scenarios: HashMap::new(),
        };

        // 注册内置场景
        manager.register_builtin_scenarios();

        manager
    }

    /// 注册内置场景
    fn register_builtin_scenarios(&mut self) {
        // 注册制造业场景
        manager.register_scenario("manufacturing_equipment", Box::new(ManufacturingEquipmentScenario::new()));

        // 注册机器人场景
        manager.register_scenario("industrial_robotics", Box::new(IndustrialRoboticsScenario::new()));

        // 注册供应链场景
        manager.register_scenario("supply_chain", Box::new(SupplyChainScenario::new()));

        // 注册交通工程场景
        manager.register_scenario("traffic_engineering", Box::new(TrafficEngineeringScenario::new()));

        // 注册智慧园区场景
        manager.register_scenario("smart_campus", Box::new(SmartCampusScenario::new()));

        // 注册能源管理场景
        manager.register_scenario("energy_management", Box::new(EnergyManagementScenario::new()));

        // 注册建筑自动化场景
        manager.register_scenario("building_automation", Box::new(BuildingAutomationScenario::new()));
    }

    /// 注册场景
    pub fn register_scenario(&mut self, name: &str, scenario: Box<dyn Scenario + Send + Sync>) {
        self.scenarios.insert(name.to_string(), scenario);
    }

    /// 获取场景
    pub fn get_scenario(&self, name: &str) -> Option<&dyn Scenario> {
        self.scenarios.get(name).map(|s| s.as_ref())
    }

    /// 列出所有场景
    pub fn list_scenarios(&self) -> Vec<&str> {
        self.scenarios.keys().map(|s| s.as_str()).collect()
    }

    /// 按行业筛选场景
    pub fn get_scenarios_by_industry(&self, industry: &str) -> Vec<&dyn Scenario> {
        self.scenarios
            .values()
            .filter(|s| s.industry() == industry)
            .map(|s| s.as_ref())
            .collect()
    }

    /// 获取场景统计信息
    pub fn get_statistics(&self) -> ScenarioStatistics {
        let mut industry_counts = HashMap::new();

        for scenario in self.scenarios.values() {
            let count = industry_counts.entry(scenario.industry()).or_insert(0);
            *count += 1;
        }

        ScenarioStatistics {
            total_scenarios: self.scenarios.len(),
            industry_distribution: industry_counts,
        }
    }
}

/// 场景统计信息
#[derive(Debug, Serialize, Deserialize)]
pub struct ScenarioStatistics {
    /// 总场景数
    pub total_scenarios: usize,
    /// 行业分布
    pub industry_distribution: HashMap<String, usize>,
}

impl Default for SceneManager {
    fn default() -> Self {
        Self::new()
    }
}

/// 场景工厂
pub struct ScenarioFactory;

impl ScenarioFactory {
    /// 创建场景
    pub fn create_scenario(scenario_type: &str, config: ScenarioConfig) -> Result<Box<dyn Scenario + Send + Sync>, String> {
        match scenario_type {
            "manufacturing_equipment" => Ok(Box::new(ManufacturingEquipmentScenario::new_with_config(config))),
            "industrial_robotics" => Ok(Box::new(IndustrialRoboticsScenario::new_with_config(config))),
            "supply_chain" => Ok(Box::new(SupplyChainScenario::new_with_config(config))),
            "traffic_engineering" => Ok(Box::new(TrafficEngineeringScenario::new_with_config(config))),
            "smart_campus" => Ok(Box::new(SmartCampusScenario::new_with_config(config))),
            "energy_management" => Ok(Box::new(EnergyManagementScenario::new_with_config(config))),
            "building_automation" => Ok(Box::new(BuildingAutomationScenario::new_with_config(config))),
            _ => Err(format!("未知的场景类型: {}", scenario_type)),
        }
    }

    /// 获取可用的场景类型
    pub fn get_available_scenarios() -> Vec<&'static str> {
        vec![
            "manufacturing_equipment",
            "industrial_robotics",
            "supply_chain",
            "traffic_engineering",
            "smart_campus",
            "energy_management",
            "building_automation",
        ]
    }
}

/// 场景配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScenarioConfig {
    /// 场景名称
    pub name: Option<String>,
    /// 描述
    pub description: Option<String>,
    /// 自定义规则
    pub custom_rules: Option<Vec<CustomRule>>,
    /// 扩展配置
    pub extensions: HashMap<String, serde_json::Value>,
}

/// 自定义规则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CustomRule {
    /// 规则名称
    pub name: String,
    /// 规则类型
    pub rule_type: String,
    /// 规则定义
    pub definition: serde_json::Value,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_scenario_manager() {
        let manager = SceneManager::new();

        // 测试场景注册
        assert!(manager.get_scenario("manufacturing_equipment").is_some());
        assert!(manager.get_scenario("nonexistent").is_none());

        // 测试场景列表
        let scenarios = manager.list_scenarios();
        assert!(!scenarios.is_empty());
        assert!(scenarios.contains(&"manufacturing_equipment"));

        // 测试按行业筛选
        let manufacturing_scenarios = manager.get_scenarios_by_industry("manufacturing");
        assert!(!manufacturing_scenarios.is_empty());

        // 测试统计信息
        let stats = manager.get_statistics();
        assert!(stats.total_scenarios > 0);
        assert!(!stats.industry_distribution.is_empty());
    }

    #[test]
    fn test_scenario_factory() {
        let available_scenarios = ScenarioFactory::get_available_scenarios();
        assert!(!available_scenarios.is_empty());

        // 测试创建已知场景
        let config = ScenarioConfig {
            name: Some("Test Scenario".to_string()),
            description: Some("Test scenario for unit testing".to_string()),
            custom_rules: None,
            extensions: HashMap::new(),
        };

        for scenario_type in &available_scenarios {
            let result = ScenarioFactory::create_scenario(scenario_type, config.clone());
            assert!(result.is_ok(), "Failed to create scenario: {}", scenario_type);
        }

        // 测试创建未知场景
        let result = ScenarioFactory::create_scenario("unknown_scenario", config);
        assert!(result.is_err());
    }
}